/*
 * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.inspur.edp.bff.designtime.generator.entity;

import com.inspur.edp.bef.bizentity.GspBizEntityObject;
import com.inspur.edp.bef.bizentity.GspBusinessEntity;
import com.inspur.edp.bff.api.attribute.VMChildAttribute;
import com.inspur.edp.bff.api.attribute.VMRootAttribute;
import com.inspur.edp.bff.designtime.generator.VmGeneratorContext;
import com.inspur.edp.caf.generator.baseInfo.AnnotationInfo;
import com.inspur.edp.caf.generator.baseInfo.AnnotationType;
import com.inspur.edp.caf.generator.baseInfo.TypeInfo;
import com.inspur.edp.cef.api.attr.ChildAttribute;
import com.inspur.edp.cef.api.attr.PropertyGetAtrribute;
import com.inspur.edp.cef.generator.entityGenerator.entity.CMEntityGeneratorContext;
import com.inspur.edp.cef.generator.overall.GenUtils;
import com.inspur.edp.das.commonmodel.IGspCommonObject;
import com.inspur.edp.formserver.viewmodel.GspViewObject;
import lombok.var;
import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.core.dom.StringLiteral;
import org.eclipse.jdt.core.dom.TypeLiteral;

import java.util.ArrayList;

public class VmEntityGenContext extends CMEntityGeneratorContext
{
	public VmEntityGenContext(VmGeneratorContext vmContext)
	{
		super(vmContext, vmContext.getVm(), vmContext.getParentVo());
		//EntityClassNameSuffix = "View";
	}
	private GspBusinessEntity privateRefBizEntity;
	public final GspBusinessEntity getRefBizEntity()
	{
		return privateRefBizEntity;
	}
	public final void setRefBizEntity(GspBusinessEntity value)
	{
		privateRefBizEntity = value;
	}
	private StringLiteral newStringLiteral(AST ast, String value)
	{
		StringLiteral stringLiteral=ast.newStringLiteral();
		stringLiteral.setLiteralValue(value);
		return stringLiteral;
	}

	public final java.util.ArrayList<AnnotationInfo> GetMainNodeAttributes(AST ast, IGspCommonObject node)
	{
		String voId = commonModel.getID();
		String beNodeCode = FindBeObjectCode(node);

		AnnotationInfo annotationInfo=new AnnotationInfo();
		annotationInfo.setTypeInfo(new TypeInfo(VMRootAttribute.class));
		addImport(VMRootAttribute.class.getTypeName());
		annotationInfo.setAnnotationType(AnnotationType.Normal);
		annotationInfo.getParams().put("objectCode",ast.newQualifiedName(ast.newSimpleName(node.getCode()+"Names"),ast.newSimpleName("NodeName")) );
		annotationInfo.getParams().put("refBEObjectCode",newStringLiteral(ast,beNodeCode));
		annotationInfo.getParams().put("voId",newStringLiteral(ast,voId));
		TypeLiteral typeLiteral=ast.newTypeLiteral();
		typeLiteral.setType(ast.newSimpleType(ast.newSimpleName("HelpMappingUtil")));
		annotationInfo.getParams().put("mappingType", typeLiteral );
		if(node.getIDElement() == null)
			throw new RuntimeException("vo["+node.getBelongModel().getCode()+"]的节点"+node.getCode()+"上没有ID字段");
		annotationInfo.getParams().put("keyFieldName",newStringLiteral(ast, node.getIDElement().getLabelID()));
		annotationInfo.getParams().put("id",newStringLiteral(ast, node.getID()));
		TypeLiteral typeLiteral1=ast.newTypeLiteral();
		typeLiteral1.setType(ast.newSimpleType(ast.newSimpleName("HelpMappingUtil")));
		annotationInfo.getParams().put("recordType", typeLiteral1 );
		ArrayList<AnnotationInfo> infos=new ArrayList<>();
		infos.add(annotationInfo);
		return infos;
	}

	public final java.util.ArrayList<AnnotationInfo> GetChildPropertyAttributes(AST ast, IGspCommonObject node)
	{
		return GetChildPropertyAttributes(ast, node, node.getCode());
	}

	public final java.util.ArrayList<AnnotationInfo> GetChildPropertyAttributes(AST ast, IGspCommonObject node, String nodeCode)
	{
		AnnotationInfo annotationInfo=new AnnotationInfo();
		annotationInfo.setTypeInfo(new TypeInfo(VMChildAttribute.class));
		String beNodeCode = FindBeObjectCode(node);
		annotationInfo.setAnnotationType(AnnotationType.Normal);
		annotationInfo.getParams().put("id",newStringLiteral(ast, node.getID()));
		annotationInfo.getParams().put("objectCode",newStringLiteral(ast,node.getCode()));
		annotationInfo.getParams().put("keyFieldName",newStringLiteral(ast,node.getIDElement().getLabelID()));
		annotationInfo.getParams().put("parentFieldName",newStringLiteral(ast,node.findElement(node.getKeys().get(0).getSourceElement()).getLabelID()));
		annotationInfo.getParams().put("refEntityObjectCode",newStringLiteral(ast,beNodeCode));
		ArrayList<AnnotationInfo> infos=new ArrayList<>();
		infos.add(annotationInfo);

		AnnotationInfo childAttributeInfo=new AnnotationInfo();
		childAttributeInfo.setAnnotationType(AnnotationType.Normal);

		var typeInfo = new TypeInfo(ChildAttribute.class);
		childAttributeInfo.setTypeInfo(typeInfo);

		var param1 = ast.newStringLiteral();
		param1.setLiteralValue(node.getCode());
		var param2 = ast.newStringLiteral();
		param2.setLiteralValue(node.getIDElement().getLabelID());
		var param3 = ast.newStringLiteral();
		param3.setLiteralValue(node.findElement(node.getKeys().get(0).getSourceElement()).getLabelID());
		var param4 = ast.newStringLiteral();
		param4.setLiteralValue(node.getID());

		childAttributeInfo.getParams().put("objectCode", param1);
		childAttributeInfo.getParams().put("keyFieldName", param2);
		childAttributeInfo.getParams().put("parentFieldName", param3);
		childAttributeInfo.getParams().put("id", param4);
		infos.add(childAttributeInfo);


		//region propertyInfo
		AnnotationInfo propAnnotation = new AnnotationInfo();
		propAnnotation.setTypeInfo(new TypeInfo(PropertyGetAtrribute.class));
		propAnnotation.setAnnotationType(AnnotationType.Normal);

		var propParam = ast.newStringLiteral();
		propParam.setLiteralValue(nodeCode);
		propAnnotation.getParams().put("propName", propParam);
		infos.add(propAnnotation);
		// endregion
		return infos;
	}

	private String FindBeObjectCode(IGspCommonObject node)
	{
		if (node.getIsVirtual())
		{
			return "";
		}
		String objectId = ((GspViewObject)node).getMapping().getTargetObjId();
//C# TO JAVA CONVERTER TODO TASK: There is no equivalent to implicit typing in Java:
		for (GspBizEntityObject beNode : getRefBizEntity().getAllNodes())
		{
			if (objectId.equals(beNode.getID()))
			{
				return beNode.getCode();
			}
		}
		return "";
	}
}
